/* 
 * Simple program to demonstrate how OSPF API can be used. This
 * application retrieves the LSDB from the OSPF daemon and then
 * originates, updates and finally deletes an application-specific
 * opaque LSA. You can use this application as a template when writing
 * your own application.
 */

/* The following includes are needed in all OSPF API client
   applications. */
#include <zebra.h>
#include "prefix.h" /* needed by ospf_asbr.h */
#include "privs.h"
#include "log.h"

#include "ospfd/ospfd.h"
#include "ospfd/ospf_asbr.h"
#include "ospfd/ospf_lsa.h"
#include "ospfd/ospf_opaque.h"
#include "ospfd/ospf_api.h"
#include "ospf_apiclient.h"

 // this inclouds needs for MYSQL
//#include <my_global.h>
#include <sqlite3.h>
#include <stdio.h>
#include <stdlib.h>  // for randome number
#include <string.h>
#include <time.h>
//#include <conio.h>


/* privileges struct. 
 * set cap_num_* and uid/gid to nothing to use NULL privs
 * as ospfapiclient links in libospf.a which uses privs.
 */
struct zebra_privs_t ospfd_privs =
{
  .user = NULL,
  .group = NULL,
  .cap_num_p = 0,
  .cap_num_i = 0
};

/*struct opaque_lsa
#  {

#  struct lsa_header header;
#  u_int16_t type;
#  u_int16_t length;
#  struct
#  {
#  		u_int16_t type;
#  		u_int16_t length;
#  		struct
#  		{
#  			u_int32_t cpu;
#  			u_int32_t ram;
#  			u_int32_t unit;
#  			char[4] location;
#  		}
#};
*/




struct cloud_data
{
	 u_int32_t CPU;
	 u_int32_t RAM;
	 u_int32_t NUMUNIT;
	 char location;

};



struct SUB_TLV3
{
	u_int16_t type;
	u_int16_t length;
	struct cloud_data router_resource;

};


struct TE_TLV5
{
	u_int16_t type;
	u_int16_t length;
	struct SUB_TLV3  subtlv3;

};


/* The following includes are specific to this application. For
   example it uses threads from libzebra, however your application is
   free to use any thread library (like pthreads). */

#include "ospfd/ospf_dump.h" /* for ospf_lsa_header_dump */
#include "thread.h"
#include "log.h"

/* Local portnumber for async channel. Note that OSPF API library will also
   allocate a sync channel at ASYNCPORT+1. */
#define ASYNCPORT 4000

/* Master thread */
struct thread_master *master;

/* Global variables */
struct ospf_apiclient *oclient;
char **args;
struct cloud_data clouddata;
struct cloud_data *cldata;


/* prototype for function using by client to send cloud data - Add by Amir Roozbeh */
int insert_new_data (float, float, int, char);
//int read_cloud_data ();
int cloud_changelog (float, float, int,char );
int read_node_data (struct thread *thread);
int db_resource_read (void);
//#define RATE = 5;
int const RATE = 5;
int counter = 0;



/* Our opaque LSAs have the following format. */
struct my_opaque_lsa
{
  struct lsa_header hdr; /* include common LSA header */
  struct cloud_data clouddata; /* our own data format then follows here */
};

/* ---------------------------------------------------------
 * Threads for asynchronous messages and LSA update/delete 
 * ---------------------------------------------------------
 */

static int
lsa_delete (struct thread *t)
{
  struct ospf_apiclient *oclient;
  struct in_addr area_id;
  int rc;

  oclient = THREAD_ARG (t);

  inet_aton (args[6], &area_id);

  printf ("Deleting LSA... ");
  rc = ospf_apiclient_lsa_delete (oclient, 
				  area_id, 
				  atoi (args[2]),       /* lsa type */
				  atoi (args[3]),	/* opaque type */
				  atoi (args[4]));	/* opaque ID */
  printf ("done, return code is = %d\n", rc);
  return rc;
}

static int
lsa_inject (struct thread *t)
{
  struct ospf_apiclient *cl;
  struct in_addr ifaddr;
  struct in_addr area_id;
  u_char lsa_type;
  u_char opaque_type;
  u_int32_t opaque_id;
  void *opaquedata;
  int opaquelen;

  static u_int32_t counter = 1;	/* Incremented each time invoked */

int rc;

  cl = THREAD_ARG (t);

  inet_aton (args[5], &ifaddr);
  inet_aton (args[6], &area_id);
  lsa_type = atoi (args[2]);
  opaque_type = atoi (args[3]);
  opaque_id = atoi (args[4]);
  opaquedata = &counter;
  opaquelen = sizeof (u_int32_t);

  printf ("Originating/updating LSA with opaquelen =%d... ",opaquelen);
  rc = ospf_apiclient_lsa_originate(cl, ifaddr, area_id,
				    lsa_type,
				    opaque_type, opaque_id,
				    opaquedata, opaquelen);

  printf ("done, return code is %d\n", rc);

counter++;

  return 0;
}

static int
lsa_inject_cloud (struct thread *t)
{

 printf ("\n************lsa_inject_cloud************\n");
 //printf ("\n consider the cloud data value as \n RAM = %f \n CPU = %f \n UNIT = %d \nTEST = %c \n",clouddata.RAM,clouddata.CPU,clouddata.NUMUNIT,clouddata.test);
 //printf ("\n consider the cloud data value as \n RAM = %f \n CPU = %f \n UNIT = %d \nTEST = %c \n",cldata->RAM,cldata->CPU,cldata->NUMUNIT,cldata->test);

  struct ospf_apiclient *cl;
  struct in_addr ifaddr;
  struct in_addr area_id;
  u_char lsa_type;
  u_char opaque_type;
  u_int32_t opaque_id;
  void *opaquedata;
  int opaquelen;
  int rc;
  struct SUB_TLV3 subtlv3;
  struct TE_TLV5  tetlv5;

  //printf ("\n LSA_INJECT_CLOUD  cldata with value of %f \n %f \n %d \n %c \nn... ",
		 // cldata->CPU,cldata->NUMUNIT,cldata->RAM,cldata->test);



  cl = THREAD_ARG (t);

  inet_aton (args[5], &ifaddr);
  inet_aton (args[6], &area_id);
  lsa_type = atoi (args[2]);
  opaque_type = atoi (args[3]); // 9 or 10 or 11 - it should be 10
  opaque_id = atoi (args[4]);

  //printf ("LSA_INJECT_CLOUD  cldata Adress = %d \n ",&clouddata);
 // printf ("LSA_INJECT_CLOUD  cldata Adress = %d \n ",cldata);

  //opaquedata = &clouddata;


  // set value of router resource data
  subtlv3.type = 3;

  subtlv3.router_resource.CPU = cldata->CPU;
  subtlv3.router_resource.RAM = cldata->RAM;
  subtlv3.router_resource.NUMUNIT = cldata->NUMUNIT;
  subtlv3.router_resource.location = cldata->location;

  // Set the length part of sub TLV of node attribute TLV which is equal to size data that carries in TLV
  subtlv3.length = sizeof (struct cloud_data);

  // Set VALU part of node att TLV
  tetlv5.subtlv3 = subtlv3;
  tetlv5.type = 5;
  //Set the length of Node Att TLV = length of sub TLV + length of type file + length of length field
  tetlv5.length = subtlv3.length + sizeof(u_int16_t) + sizeof(u_int16_t);



 // opaquedata = cldata;
  // The Node Att TLV - TLV type  = 5 TE LSA is a opaque data
  opaquedata = &tetlv5;



// Set the length of Opaque data = length part  TLV  + length of type filed + length of length field
  opaquelen = tetlv5.length + sizeof(u_int16_t) + sizeof(u_int16_t);

  printf ("Originating/updating LSA for Cloud with counter=... \n");
  rc = ospf_apiclient_lsa_originate(cl, ifaddr, area_id,
				    lsa_type,
				    opaque_type, opaque_id,
				    opaquedata, opaquelen);

  printf ("done, return code is %d\n", rc);

  return 0;
}



/* This thread handles asynchronous messages coming in from the OSPF
   API server */
static int
lsa_read (struct thread *thread)
{

  struct ospf_apiclient *oclient;
  int fd;
  int ret;

  printf ("\nlsa_read called\n");
  oclient = THREAD_ARG (thread);
  fd = THREAD_FD (thread);

  /* Handle asynchronous message */
  ret = ospf_apiclient_handle_async (oclient);
  if (ret < 0) {
    printf ("Connection closed, exiting...");
    exit(0);
  }

  /* Reschedule read thread */
  thread_add_read (master, lsa_read, oclient, fd);

  return 0;
}

/* ---------------------------------------------------------
 * Callback functions for asynchronous events 
 * ---------------------------------------------------------
 */

static void
lsa_update_callback (struct in_addr ifaddr, struct in_addr area_id,
		     u_char is_self_originated,
		     struct lsa_header *lsa)
{
  printf ("lsa_update_callback: ");
  printf ("ifaddr: %s ", inet_ntoa (ifaddr));
  printf ("area: %s\n", inet_ntoa (area_id));
  printf ("is_self_origin: %u\n", is_self_originated);

  /* It is important to note that lsa_header does indeed include the
     header and the LSA payload. To access the payload, first check
     the LSA type and then typecast lsa into the corresponding type,
     e.g.:
     
     if (lsa->type == OSPF_ROUTER_LSA) {
       struct router_lsa *rl = (struct router_lsa) lsa;
       ...
       u_int16_t links = rl->links;
       ...
    }
  */
       
  ospf_lsa_header_dump (lsa);
}

static void
lsa_delete_callback (struct in_addr ifaddr, struct in_addr area_id,
		     u_char is_self_originated,
		     struct lsa_header *lsa)
{
  printf ("lsa_delete_callback: ");
  printf ("ifaddr: %s ", inet_ntoa (ifaddr));
  printf ("area: %s\n", inet_ntoa (area_id));
  printf ("is_self_origin: %u\n", is_self_originated);

  ospf_lsa_header_dump (lsa);
}

static void
ready_callback (u_char lsa_type, u_char opaque_type, struct in_addr addr)
{
  printf ("\n ready_callback: lsa_type: %d opaque_type: %d addr=%s\n",
	  lsa_type, opaque_type, inet_ntoa (addr));

 // thread_add_timer (master, read_node_data, oclient, 5);


  /* Schedule opaque LSA originate in 5 secs */
  //thread_add_timer (master, lsa_inject_cloud, oclient, 0);

  /* Schedule opaque LSA update with new value */
  //thread_add_timer (master, lsa_inject, oclient, 1);

  /* Schedule delete */
  //thread_add_timer (master, lsa_delete, oclient, 2);


}

static void
new_if_callback (struct in_addr ifaddr, struct in_addr area_id)
{
  printf ("new_if_callback: ifaddr: %s ", inet_ntoa (ifaddr));
  printf ("area_id: %s\n", inet_ntoa (area_id));
}

static void
del_if_callback (struct in_addr ifaddr)
{
  printf ("new_if_callback: ifaddr: %s\n ", inet_ntoa (ifaddr));
}

static void
ism_change_callback (struct in_addr ifaddr, struct in_addr area_id,
		     u_char state)
{
  printf ("ism_change: ifaddr: %s ", inet_ntoa (ifaddr));
  printf ("area_id: %s\n", inet_ntoa (area_id));
  printf ("state: %d [%s]\n", state, LOOKUP (ospf_ism_state_msg, state));
}

static void
nsm_change_callback (struct in_addr ifaddr, struct in_addr nbraddr,
		     struct in_addr router_id, u_char state)
{
  printf ("nsm_change: ifaddr: %s ", inet_ntoa (ifaddr));
  printf ("nbraddr: %s\n", inet_ntoa (nbraddr));
  printf ("router_id: %s\n", inet_ntoa (router_id));
  printf ("state: %d [%s]\n", state, LOOKUP (ospf_nsm_state_msg, state));
}






/* ---------------------------------------------------------
 * Main program 
 * ---------------------------------------------------------
 */

static int usage()
{
  printf("Usage: ospfclient <ospfd> <lsatype> <opaquetype> <opaqueid> <ifaddr> <areaid>\n");
  printf("where ospfd     : router where API-enabled OSPF daemon is running\n");
  printf("      lsatype   : either 9, 10, or 11 depending on flooding scope\n");
  printf("      opaquetype: 0-255 (e.g., experimental applications use > 128)\n");
  printf("      opaqueid  : arbitrary application instance (24 bits)\n");
  printf("      ifaddr    : interface IP address (for type 9) otherwise ignored\n");
  printf("      areaid    : area in IP address format (for type 10) otherwise ignored\n");
  
  exit(1);
}

int
main (int argc, char *argv[])
{
  struct thread thread;
  args = argv;
  int stat; // keep the state of reading node data

  /* ospfclient should be started with the following arguments:
   * 
   * (1) host (2) lsa_type (3) opaque_type (4) opaque_id (5) if_addr 
   * (6) area_id
   * 
   * host: name or IP of host where ospfd is running
   * lsa_type: 9, 10, or 11
   * opaque_type: 0-255 (e.g., experimental applications use > 128) 
   * opaque_id: arbitrary application instance (24 bits)
   * if_addr: interface IP address (for type 9) otherwise ignored
   * area_id: area in IP address format (for type 10) otherwise ignored
   */

  if (argc != 7)
    {
      usage();
    }
  /* Initialization */
  printf("Initialization ......\n\n ");

  printf("set ospfd_prives primetive value by calling  zprivs_init (&ospfd_privs)......\n\n ");
  zprivs_init (&ospfd_privs);

  printf("creating thread master by calling master = thread_master_create ()....\n\n" );
  master = thread_master_create ();

  printf("master thread is created as following : \n"
		  "******************\n\n\n");

  /* Open connection to OSPF daemon */
  printf("Try to open the connection to OSPF daemon\n");
  printf("  oclient = ospf_apiclient_connect (args[1], ASYNCPORT) \n which args[1]: %s \n and ASYNCPORT is : %d \n\n\n",args[1],ASYNCPORT);
  oclient = ospf_apiclient_connect (args[1], ASYNCPORT);
  if (!oclient)
    {
      printf ("Connecting to OSPF daemon on %s FAILED!\n",
	      args[1]);
      exit (1);
    }
  else
	  printf ("Connecting to OSPF daemon on %s ESTABLISHED!\n\n",
	 	      args[1]);


  /* Register callback functions. */

  printf(" Registering call back functions to oclinet. */\n\n");

  printf("call ospf_apiclient_register_callback (oclient,\n"
		  "  ready_callback,\n"
		  "  new_if_callback, \n"
		  "  del_if_callback,\n"
		  " ism_change_callback,\n"
		  "  nsm_change_callback,\n"
		  "  lsa_update_callback, \n"
		  "  lsa_delete_callback);\n\n\n\n");


  ospf_apiclient_register_callback (oclient,
				    ready_callback,
				    new_if_callback,
				    del_if_callback,
				    ism_change_callback,
				    nsm_change_callback,
				    lsa_update_callback, 
				    lsa_delete_callback);

  /* Register LSA type and opaque type. */

  printf("  /* Register LSA type and opaque type. */\n\n");
  printf("call spf_apiclient_register_opaque_type (oclient, atoi (args[2]),atoi (args[3])) which \n args[2] is <opaquetype> : %s \n "
		  "and args[3] is  <opaqueid> : %s \n\n\n\n",args[2],args[3]);

  ospf_apiclient_register_opaque_type (oclient, atoi (args[2]),
				       atoi (args[3]));



  /* Synchronize database with OSPF daemon. */

  printf("  /* Synchronize database with OSPF daemon. */\n\n");
  printf("call ospf_apiclient_sync_lsdb (oclient);\n\n\n\n");
  ospf_apiclient_sync_lsdb (oclient);

  /* Schedule thread that handles asynchronous messages */
  printf("  /* Schedule thread that handles asynchronous messages */ \n \n");
  printf("call   thread_add_read (master, lsa_read, oclient, oclient->fd_async); \n\n\n\n\n");
  printf("#define thread_add_read(m,f,a,v) funcname_thread_add_read(m,f,a,v,#f)");

    thread_add_read (master, lsa_read, oclient, oclient->fd_async);
    thread_add_timer (master, read_node_data, oclient, 5);


printf("  /* Now connection is established, run loop \n\n\n*/");

/* This part is variable and values using bu client to send cloud data */


/*
clouddata.CPU = 585;
clouddata.RAM = 128;
clouddata.NUMUNIT = 855;
clouddata.test = 15;
*/

cldata = &clouddata;


//printf ("MAIN \n  cldata with value of %d \n %d \n %d \n %d \nn... "
		//,(*cldata).CPU,(*cldata).NUMUNIT,(*cldata).RAM,(*cldata).test);

//printf ("MAIN \n  cloud data befor entering the while with original DATA \n  CPU = %f \n RAM = %f \n UNIT = %d \n TEST = %c \nn... ",clouddata.CPU,clouddata.RAM,clouddata.NUMUNIT,clouddata.test);
//printf ("MAIN \n  cloud data befor entering the while with POINTER \n  CPU = %f \n RAM = %f \n UNIT = %d \n TEST = %c \nn... ",cldata->CPU,cldata->RAM,cldata->NUMUNIT,cldata->test);

printf ("MAIN \n  cldata Adress = %d \n ", &cldata);



  while (1)
   {
	//delay(1000);
	sleep(2);
	thread_fetch (master, &thread);
	thread_call (&thread);

	/*
	stat = read_node_data ();
	  if (stat == 0)
	  {
		  //lsa_inject_cloud(&thread);
		printf(" \n\ After Status is OK befor calling the lsa_inject_ cloud \n CPU = %f \n RAM = %f \n UNIT  = %d \n  test = %c \n",clouddata.CPU,clouddata.RAM,clouddata.NUMUNIT,clouddata.test);
		//thread_add_timer (master, lsa_inject_cloud, oclient, 1);
		//thread_fetch (master, &thread);
		//thread_call (&thread);

	  }
	  else
	  {
		  thread_fetch (master, &thread);
		  thread_call (&thread);
	  }


	  //else if (stat == -1)
		// getchar();

	  //thread_fetch (master, &thread);
      //thread_call (&thread);       */
    }


  /* Never reached */
  return 0;
}


int
insert_new_data (float acloud, float bcloud, int ccluod, char dcluod)
{
	//printf("\n VERSION 222222222");

	//printf(" \n\ insert_new_data called by  \n a = %f \n b = %f \n c  = %d \n  d = %c \n",acloud,bcloud,ccluod,dcluod);
	/*
	cldata->RAM = a;
	cldata->CPU = b;
	cldata->NUMUNIT = c;
	cldata->test = d;
	printf(" \n\ cloud data nvalue change to  \n CPU = %f \n RAM = %f \n UNIT  = %d \n  test = %c \n",
			cldata->CPU,cldata->RAM,cldata->NUMUNIT,cldata->test); */

	/*clouddata.CPU = a;
	printf("\nclouddata.CPU= %f and a = % f \n ",clouddata.CPU,a);
	clouddata.RAM = b;
	printf("\nclouddata.RAM= %f and b = % f \n",clouddata.RAM,b);
	clouddata.NUMUNIT = c;
	printf("\nclouddata.NUMUNIT= %d and c = %d \n ",clouddata.NUMUNIT,c);

	clouddata.test = d;
	printf("clouddata.test= %c and a = %c ",clouddata.test,d);*/

		cldata->CPU = acloud;
		//printf("\nclouddata.CPU= %f  \n ",cldata->CPU);
		//printf("\n and a = % f \n ",acloud);

		cldata->RAM = bcloud;
		//printf("\nclouddata.RAM= %f \n",cldata->RAM);
		//printf("\nand b = % f \n",bcloud);


		clouddata.NUMUNIT = ccluod;
		//printf("\nclouddata.NUMUNIT= %d \n ",cldata->NUMUNIT);
		//printf("\n and c = %d \n ",ccluod);


		cldata->location = dcluod;
		//printf("clouddata.test= %c ",cldata->test);
		//printf("d = %c ",dcluod);



		//printf(" \n\ cloud data after insert value change to  \n CPU = %f \n RAM = %f \n UNIT  = %d \n  test = %c \n",
				//clouddata.CPU,clouddata.RAM,clouddata.NUMUNIT,clouddata.test);

		//printf(" \n\ cloud data after insert value change to  \n CPU = %f \n RAM = %f \n UNIT  = %d \n  test = %c \n",cldata->CPU,cldata->RAM,cldata->NUMUNIT,cldata->test);

	return 0;
}


int db_resource_read ()

{
	counter++;
	printf("\n\n\n insert to db_resource_read () \n\n\n");
		// thuis function will read the data from sqlite data base and if it meet the requirement it will update the the cloud data structure

		int retval;     // Create an int variable for storing the return code for each call
		char string[150];
		sqlite3 *conn;     // Create a handle for database connection, create a pointer to sqlite3
		char *database = "resource.db";
		sqlite3_stmt *stmt;     // A prepered statement for fetching tables
		int cols; // number of cuolums of tabale
		float CPU = 0.0;
		float RAM = 0.0;
		int NUMUNIT = 0;
		char location = 'N';
		int rsv;
		int i;

		// try to create the database. If it doesnt exist, it would be created
		retval = sqlite3_open(database,&conn);  //pass a pointer to the pointer to sqlite3, in short sqlite3**

		// error handeling ---If connection failed, conn returns NULL
		if(retval)
		{
			printf("Database connection failed\n %d \n",retval);
			printf("counter = %d\n",counter);
			//getchar();
		    return -1;
		}
		//else
			//printf("Connection successful\n");


		// Set the string     // select those rows from the table
		memset(string, 0, sizeof(string));
		sprintf(string, "SELECT * from resource");

		retval = sqlite3_prepare_v2(conn,string,-1,&stmt,0);
		if(retval)
		{
			printf("Selecting data from DB Failed\n");
			sqlite3_finalize(stmt);
			rsv=sqlite3_close(conn);
			//getchar();
			return -1;
		}

		    // Read the number of rows fetched
		cols = sqlite3_column_count(stmt);

		//printf("number of colums are \n  %d ", cols);

		while(1)
		{
			// fetch a row's status
		    retval = sqlite3_step(stmt);

		    if(retval == SQLITE_ROW)
		    {
		    	// SQLITE_ROW means fetched a row
		        // sqlite3_column_text returns a const void* , typecast it to const char*
		        for(i=0 ; i<cols;i++)
		        {
		        	// copy the value of culom i to val
		            const char *val = (const char*)sqlite3_column_text(stmt,i);
		            // printf("%s = %s\t \n",sqlite3_column_name(stmt,i),val);
		            switch(i)
		            {
		            case 0:
		            	CPU = atof(val);
		            	//printf("the value in numeric is %f and i is %d \n",CPU, i);
		            	break;

		            case 1:
		            	RAM = atof(val);
		            	//printf("the value in numeric is %f and i is %d \n",RAM, i);
		            	break;


		            case 2:
		            	NUMUNIT = atoi(val);
		            	//printf("the value in numeric is %d and i is %d \n",NUMUNIT, i);
		            	break;

		            case 3:
		            	location = *val;
		            	//printf("the value in numeric is %s and i is %d \n",test, i);
		            	break;

		            }
			       // printf(" exit from for\n");
		        }
		    }
		    else if(retval == SQLITE_DONE)
		    {
		    	// All rows finished
		       printf("\n All rows fetched\n");
		       //sqlite3_finalize(stmt);
		       //sqlite3_close(conn);
		       break;
		    }
		    else
		    {
		    	// Some error encountered
		        printf("\n Some error encountered \n");
		        sqlite3_finalize(stmt);
		        sqlite3_close(conn);
		        //getchar();
		        return -1;
		    }
		}

		// Close the handle to free memory
		sqlite3_finalize(stmt);
		rsv=sqlite3_close(conn);
	/*if (rsv == 0)
	    	printf("\nclose with zero mean sucess\n = %d \n",rsv);
	    else
	    	printf("\nclose with NOT ZERO sucess\n = %d \n",rsv);
	*/
		rsv = cloud_changelog(CPU,RAM,NUMUNIT,location);
		printf ("\nEXIT\n");
		return rsv;
}

int read_node_data(struct thread *thread)
{
	int rsv;
	rsv = db_resource_read();

    if (rsv == 0)
    {
    	//printf("thread_add_timer (master, lsa_inject_cloud, oclient, 0);\n NEW DATA \n NEXT step is LSA INJECT\n");
    	//getchar();
		//thread_add_timer (master, lsa_inject_cloud, oclient, 1);
    	//thread_add_timer (master, read_node_data, oclient, 5);
    	printf("\nNEW DTATA ---------CALLING LSA INJEC\n");
    	thread_add_timer (master, lsa_inject_cloud, oclient, 1); // this is for addding the reading base on thread
        thread_add_timer (master, read_node_data, oclient, 5);
    	return 0; // New cloud data received
    }

    else
    {
    	//printf("thread_add_timer (master, lsa_inject_cloud, oclient, 0);\n NOOOOOOOOO DATA");
    	//getchar();
    	//thread_add_timer (master, read_node_data, oclient, 5);
    	printf("\n NOT  DTATA ---------\n");
        thread_add_timer (master, read_node_data, oclient, 5);
    	return 1; // there is no new data for cloud

    }
}



/*


int read_node_data()
{

	printf("insert to Read_node_data() \n\n\n");
	// thuis function will read the data from sqlite data base and if it meet the requirement it will update the the cloud data structure

	int retval;     // Create an int variable for storing the return code for each call
	char string[150];
	sqlite3 *conn;     // Create a handle for database connection, create a pointer to sqlite3
	char *database = "resource.db";
	sqlite3_stmt *stmt;     // A prepered statement for fetching tables
	int cols; // number of cuolums of tabale
	float CPU = 0.0;
	float RAM = 0.0;
	int NUMUNIT = 0;
	char location = 'N';
	int rsv;
	int i;

//	while (1)
	//{
	 // Conection to database /
	/// try to create the database. If it doesnt exist, it would be created
/*	retval = sqlite3_open(database,&conn);  //pass a pointer to the pointer to sqlite3, in short sqlite3**

	// error handeling ---If connection failed, conn returns NULL
	if(retval)
	{
		printf("Database connection failed\n");
	    return -1;
	}
	else
		printf("Connection successful\n");


	// Set the string     // select those rows from the table
	memset(string, 0, sizeof(string));
	sprintf(string, "SELECT * from resource");

	retval = sqlite3_prepare_v2(conn,string,-1,&stmt,0);
	if(retval)
	{
		printf("Selecting data from DB Failed\n");
	    return -1;
	}

	    // Read the number of rows fetched
	cols = sqlite3_column_count(stmt);

	printf("number of colums are \n  %d ", cols);

	while(1)
	{
		// fetch a row's status
	    retval = sqlite3_step(stmt);

	    if(retval == SQLITE_ROW)
	    {
	    	// SQLITE_ROW means fetched a row
	        // sqlite3_column_text returns a const void* , typecast it to const char*
	        for(i=0 ; i<cols;i++)
	        {
	        	// copy the value of culom i to val
	            const char *val = (const char*)sqlite3_column_text(stmt,i);
	            // printf("%s = %s\t \n",sqlite3_column_name(stmt,i),val);
	            switch(i)
	            {
	            case 0:
	            	CPU = atof(val);
	            	//printf("the value in numeric is %f and i is %d \n",CPU, i);
	            	break;

	            case 1:
	            	RAM = atof(val);
	            	//printf("the value in numeric is %f and i is %d \n",RAM, i);
	            	break;


	            case 2:
	            	NUMUNIT = atoi(val);
	            	//printf("the value in numeric is %d and i is %d \n",NUMUNIT, i);
	            	break;

	            case 3:
	            	location = *val;
	            	//printf("the value in numeric is %s and i is %d \n",test, i);
	            	break;

	            }
		        printf(" exit from for\n");
	        }
	    }
	    else if(retval == SQLITE_DONE)
	    {
	    	// All rows finished
	        printf("All rows fetched\n");
	    	break;
	    }
	    else
	    {
	    	// Some error encountered
	        printf("Some error encountered\n");
	        return -1;
	    }
	}

	// Close the handle to free memory
	sqlite3_finalize(stmt);
	sqlite3_close(conn);
	rsv = cloud_changelog(CPU,RAM,NUMUNIT,location);
    if (rsv == 0)
    	return 0; // New cloud data received
    else
    	return 1; // there is no new data for cloud
    }

*/

int cloud_changelog(float CPU,float RAM,int NUMUNIT,char location)
{
	//printf("Insert to change log of data \n\n\n\n");
	//if (a > 2*clouddata.CPU || b > 2*clouddata.RAM || c > 2*clouddata.NUMUNIT || 2*a < clouddata.CPU || 2*b < clouddata.RAM || 2*c < clouddata.NUMUNIT)
	if (CPU > RATE*cldata->CPU || RAM > RATE*cldata->RAM || NUMUNIT > RATE*cldata->NUMUNIT || RATE*CPU < cldata->CPU || RATE*RAM < cldata->RAM || RATE*NUMUNIT < cldata->NUMUNIT)
	{
		insert_new_data(CPU,RAM,NUMUNIT,location);
	    return 0;
	 }
   	else
   	{
   		//printf("NO CHANGE");
	    return 1;
   	}
}
/*
int read_cloud_data ()
{
	float acloud;
	float bcloud;
	int ccloud;
	char dcloud;

	printf("\n insert value for CPU \n");
	scanf("%f", &acloud);
	printf("\n A = %f \n",acloud);


	printf("\n insert value for RAM \n");
	scanf("%f", &bcloud);
	printf("\n B = %f \n",bcloud);


	printf("\n insert value for UNITTT \n");
		scanf("%d", &ccloud);
		printf("\n C = %d \n",ccloud);

	dcloud = 'p';
	//printf("\n insert value for test \n");
	//d = getchar();
	//scanf("%c",d);
	printf("\n test = %c \n",dcloud);


	if (acloud > 2*cldata->CPU || bcloud > 2*cldata->RAM || ccloud > 2*cldata->NUMUNIT || 2*acloud < cldata->CPU || 2*bcloud < cldata->RAM || 2*ccloud < cldata->NUMUNIT)
	//if (a > 2*clouddata.CPU || b > 2*clouddata.RAM || c > 2*clouddata.NUMUNIT || 2*a < clouddata.CPU || 2*b < clouddata.RAM || 2*c < clouddata.NUMUNIT)
		{
			insert_new_data(acloud,bcloud,ccloud,dcloud);
			return 0;

		 }
	else
		{
			printf("NO CHANGE");
			return 1;
		}
}
*/
